﻿/***************************************************************
 * 开发人员：网魂小兵@http://www.mozlite.com
 * 
 * 目标标本：4.0.30319.239
 * 
 * 最后修改：2011/11/12 13:41:40
 * ************************************************************/
namespace Mozlite.FileStorages
{
    using System;
    using System.Linq;
    using System.Text;
    using System.Collections.Generic;
    using Mozlite.Common.Configuration;

    /// <summary>
    /// 存储管理类。
    /// </summary>
    public class Storages
    {
        private Storages() { }

        /// <summary>
        /// 保存文件夹。
        /// </summary>
        /// <param name="folder">文件夹实例对象。</param>
        /// <returns>返回文件夹状态。</returns>
        public static FileStorageStatus CreateFolder(UserFolder folder) {
            if (!folder.Parent.IsNameValided(folder.FolderName))
                return FileStorageStatus.DuplicateFolderName;
            var status = FileStorageDataProvider.Current.CreateFolder(folder);
            if (status == FileStorageStatus.Created)
            {
                Caches.Remove(GetFolderKey(folder.UserID));
            }
            return status;
        }

        /// <summary>
        /// 改变文件夹名称。
        /// </summary>
        /// <param name="folderID">文件夹ID。</param>
        /// <param name="folderName">文件夹名称。</param>
        /// <returns>返回文件存储状态。</returns>
        public static FileStorageStatus ChangeFolderName(UserFolder folder)
        {
            var status = FileStorageDataProvider.Current.ChangeFolderName(folder.FolderID/*, folder.SettingsID*/, folder.UserID, folder.FolderName);
            if (status == FileStorageStatus.Updated)
            {
                RemoveCache(folder.UserID);
            }
            return status;
        }

        private static string GetFolderKey(int userID)
        {
            return string.Format("FileStorages::Folders::{0}", userID);
            //return string.Format("FileStorages::Folders::{0}::SettingsID::{1}", userID, SiteSettings.Current.SettingsID);
        }

        /// <summary>
        /// 获取用户所有文件夹列表，文件夹ID。
        /// </summary>
        /// <param name="userID">用户ID。</param>
        /// <returns>返回文件夹列表。</returns>
        public static Dictionary<int, UserFolder> GetFolders(int userID)
        {
            return Caches.Get<Dictionary<int, UserFolder>>(GetFolderKey(userID), Globals.MinuteSeconds, Globals.MinuteSeconds, () =>
            {
                return FileStorageDataProvider.Current.GetFolders(/*SiteSettings.Current.SettingsID,*/ userID);
            });
        }

        /// <summary>
        /// 获取用户所有文件夹列表，文件夹ID。
        /// </summary>
        /// <returns>返回文件夹列表。</returns>
        public static Dictionary<int, UserFolder> GetFolders()
        {
            return GetFolders(AppContext.Current.User.UserID);
        }

        /// <summary>
        /// 获取图标。
        /// </summary>
        /// <param name="mode">图标模式。</param>
        /// <param name="fileName">文件名。</param>
        /// <returns>返回图标路径。</returns>
        public static string GetIconUrl(FileIconMode mode, string fileName) {
            return Globals.GetUtil("icons", mode, fileName + ".gif");
        }

        /// <summary>
        /// 获取文件图标。
        /// </summary>
        /// <param name="mode">图标模式。</param>
        /// <param name="extension">文件扩展名。</param>
        /// <returns>返回图标路径。</returns>
        public static string GetFileIconUrl(FileIconMode mode, string extension)
        {
            return Globals.GetUtil("icons/files", mode, extension + ".gif");
        }

        /// <summary>
        /// 获取文件夹目录树，键值为层次。
        /// </summary>
        /// <param name="folderID">当前目录ID。</param>
        /// <returns>返回文件夹列表。</returns>
        public static Dictionary<int, UserFolder> GetFolderTrees(int folderID) {
            var folders = new Dictionary<int, UserFolder>();
            UserFolder folder;
            if (!GetFolders().TryGetValue(folderID, out folder))
                return folders;
            int index = 0;
            do
            {
                folders.Add(index++, folder);
                GetFolders().TryGetValue(folder.ParentID, out folder);
            } while (folder != null);
            return folders;
        }

        /// <summary>
        /// 获取根目录文件夹列表。
        /// </summary>
        /// <returns>返回根目录文件夹列表。</returns>
        public static List<UserFolder> GetRootFolders() {
            var folders = from folder in GetFolders().Values
                          where folder.ParentID == 0
                          select folder;
            if (folders != null)
                return folders.ToList<UserFolder>();
            return null;
        }

        private static string GetFileKey(int userID)
        {
            return string.Format("FileStorages::Files::{0}", userID);
            //return string.Format("FileStorages::Files::{0}::SettingsID::{1}", userID, SiteSettings.Current.SettingsID);
        }

        /// <summary>
        /// 获取用户所有文件列表，文件夹ID。
        /// </summary>
        /// <param name="userID">用户ID。</param>
        /// <returns>返回文件列表。</returns>
        public static Dictionary<int, List<UserFile>> GetFiles(int userID)
        {
            return Caches.Get<Dictionary<int, List<UserFile>>>(GetFileKey(userID), Globals.MinuteSeconds, Globals.MinuteSeconds, () =>
            {
                return FileStorageDataProvider.Current.LoadFiles(/*SiteSettings.Current.SettingsID,*/ userID);
            });
        }

        /// <summary>
        /// 获取用户所有文件列表，文件夹ID。
        /// </summary>
        /// <returns>返回文件列表。</returns>
        public static Dictionary<int, List<UserFile>> GetFiles()
        {
            return GetFiles(AppContext.Current.User.UserID);
        }

        /// <summary>
        /// 移动文件夹。
        /// </summary>
        /// <param name="srcID">原文件夹。</param>
        /// <param name="desID">目标文件夹。</param>
        /// <param name="settingsID">网站设置ID。</param>
        /// <param name="userID">用户ID。</param>
        /// <returns>返回文件存储状态。</returns>
        public static FileStorageStatus MoveFolder(int srcID, int desID)
        {
            UserFolder src, des;
            if (GetFolders().TryGetValue(srcID, out src))
            {
                if (!GetFolders().TryGetValue(desID, out des))
                    des = new UserFolder();
                if(!des.IsNameValided(src.FolderName))
                    return FileStorageStatus.DuplicateFolderName;
                var status = FileStorageDataProvider.Current.MoveFolder(srcID, desID/*, src.SettingsID*/, src.UserID);
                if (status == FileStorageStatus.Moved)
                {
                    RemoveCache(src.UserID);
                }
                return status;
            }
            return FileStorageStatus.FolderNotFound;
        }

        private static void RemoveCache(int userID = -1)
        {
            if (userID == -1)
                userID = AppContext.Current.User.UserID;
            Caches.Remove(GetFolderKey(userID));
            Caches.Remove(GetFileKey(userID));
        }

        private static readonly string cacheKey = "DiskUsages::UserID.{0}";//"DiskUsages::SettingsID.{0}::UserID.{1}";

        /// <summary>
        /// 获取磁盘使用量。
        /// </summary>
        /// <returns>返回磁盘使用量。</returns>
        public static long GetDiskUsage() {
            int userID = AppContext.Current.User.UserID;
            string key = string.Format(cacheKey/*, SiteSettings.Current.SettingsID*/, userID);
            object usage = Caches.Get(key);
            if (usage == null)
            {
                long size = FileStorageDataProvider.Current.GetDiskUsage(/*SiteSettings.Current.SettingsID, */userID);
                usage = Caches.Max(key, size, new System.Web.Caching.CacheDependency(null, new string[] { GetFileKey(userID) }));
            }
            return (long)usage;
        }

        /// <summary>
        /// 保存用户文件。
        /// </summary>
        /// <param name="file">用户文件实例。</param>
        /// <returns>返回文件存储状态。</returns>
        public static FileStorageStatus SaveFile(UserFile file)
        {
            var status = FileStorageDataProvider.Current.SaveFile(file);
            if (status == FileStorageStatus.Created || status == FileStorageStatus.Updated)
            {
                RemoveCache(file.UserID);
            }
            return status;
        }

        /// <summary>
        /// 获取文件实例。
        /// </summary>
        /// <param name="fileID">文件ID。</param>
        /// <returns>返回用户文件。</returns>
        public static UserFile GetFile(int fileID)
        {
            return FileStorageDataProvider.Current.GetFile(/*SiteSettings.Current.SettingsID,*/ AppContext.Current.User.UserID, fileID);
        }

        /// <summary>
        /// 移动文件。
        /// </summary>
        /// <param name="fileID">文件ID。</param>
        /// <param name="folderID">文件夹ID。</param>
        /// <returns>返回文件存储状态。</returns>
        public static FileStorageStatus MoveFile(int fileID, int folderID)
        {
            UserFolder folder;
            if (!GetFolders().TryGetValue(folderID, out folder))
                folder = new UserFolder();
            if (!folder.IsNameValided(GetFile(fileID).FullName))
                return FileStorageStatus.DuplicateFileName;
            var status = FileStorageDataProvider.Current.MoveFile(fileID, folderID/*, SiteSettings.Current.SettingsID*/, AppContext.Current.User.UserID);
            if (status == FileStorageStatus.Moved)
                RemoveCache(AppContext.Current.User.UserID);
            return status;
        }

        /// <summary>
        /// 计算文件夹大小。
        /// </summary>
        public static void CalculateFolderSize() {
            FileStorageDataProvider.Current.CalculateFolderSize();
        }

        /// <summary>
        /// 删除文件夹。
        /// </summary>
        /// <param name="folderID">文件夹ID。</param>
        /// <returns>返回执行结果。</returns>
        public static bool DeleteFolder(int folderID)
        {
            int userID = AppContext.Current.User.UserID;
            if (FileStorageDataProvider.Current.DeleteFolder(/*SiteSettings.Current.SettingsID,*/ userID, folderID))
            {
                RemoveCache(userID);
                return true;
            }
            return false;
        }

        /// <summary>
        /// 删除文件。
        /// </summary>
        /// <param name="fileID">文件ID。</param>
        /// <returns>返回执行结果。</returns>
        public static bool DeleteFile(int fileID)
        {
            int userID = AppContext.Current.User.UserID;
            if (FileStorageDataProvider.Current.DeleteFile(/*SiteSettings.Current.SettingsID,*/ userID, fileID))
            {
                RemoveCache(userID);
                return true;
            }
            return false;
        }

        /// <summary>
        /// 从缓存中获取用户文件夹，如果不存在则初始化一个实例。
        /// </summary>
        /// <param name="folderID">文件夹ID。</param>
        /// <returns>返回用户文件夹实例对象。</returns>
        public static UserFolder GetFolderFromCache(int folderID)
        {
            UserFolder folder;
            if (GetFolders().TryGetValue(folderID, out folder))
                return folder;
            return new UserFolder();
        }

        /// <summary>
        /// 获取文件实例。
        /// </summary>
        /// <param name="fileID">文件ID。</param>
        /// <returns>返回用户文件实例。</returns>
        public static UserFile GetStorage(int fileID)
        {
            return FileStorageDataProvider.Current.GetStorage(fileID);
        }
    }
}